[−][src]Crate building_blocks_mesh
Algorithms for generating triangle meshes from:
- height maps
- signed distance fields
- voxel occupancy grids
All of the algorithms are designed to be used with a ChunkMap
, such that each chunk will have
its own mesh. In order to update the mesh for a chunk, you must copy not only the chunk, but
also some adjacent points, into an array before running the meshing algorithm.
An example of updating chunk meshes for a height map is shown below. The same general pattern applies to all meshing algorithms, where you:
- get the desired chunk extent
- pad the extent for a particular meshing algorithm
- copy that extent into an array
- mesh that array
use building_blocks_core::prelude::*; use building_blocks_storage::prelude::*; use building_blocks_mesh::height_map::*; use std::collections::HashSet; let chunk_shape = PointN([16; 2]); let mut map = ChunkMap2::new(chunk_shape, 0.0, (), FastLz4 { level: 10 }); // Mutate one or more of the chunks... let mutated_chunk_keys = [PointN([0; 2]), PointN([16; 2])]; // For each mutated chunk, and any adjacent chunk, the mesh will need to be updated. let mut chunk_keys_to_update: HashSet<Point2i> = HashSet::new(); let offsets = Point2i::moore_offsets(); for chunk_key in mutated_chunk_keys.into_iter() { chunk_keys_to_update.insert(*chunk_key); for offset in offsets.iter() { chunk_keys_to_update.insert(*chunk_key + *offset * chunk_shape); } } // Now we generate mesh vertices for each chunk. let local_cache = LocalChunkCache2::new(); let reader = ChunkMapReader2::new(&map, &local_cache); for chunk_key in chunk_keys_to_update.into_iter() { // It's crucial that we pad the chunk so we have access to adjacent points during meshing. let padded_chunk_extent = padded_height_map_chunk_extent( &map.extent_for_chunk_at_key(&chunk_key) ); let mut padded_chunk = Array2::fill(padded_chunk_extent, 0.0); copy_extent(&padded_chunk_extent, &reader, &mut padded_chunk); let mut hm_buffer = HeightMapMeshBuffer::default(); triangulate_height_map(&padded_chunk, &padded_chunk_extent, &mut hm_buffer); // Do something with the mesh output... }
All of the meshing algorithms are generic enough to work with an array wrapped in a
TransformMap
.
struct OtherHeight(f32); impl Height for OtherHeight { fn height(&self) -> f32 { self.0 } } let extent = Extent2i::from_min_and_shape(PointN([0; 2]), PointN([50; 2])); let array = Array2::fill(extent, 0.0); let tfm_array = TransformMap::new(&array, |h: f32| OtherHeight(h)); let mut hm_buffer = HeightMapMeshBuffer::default(); triangulate_height_map(&tfm_array, &extent, &mut hm_buffer);
Re-exports
pub use greedy_quads::greedy_quads; |
pub use greedy_quads::padded_greedy_quads_chunk_extent; |
pub use greedy_quads::GreedyQuadsBuffer; |
pub use greedy_quads::MaterialVoxel; |
pub use greedy_quads::Quad; |
pub use height_map::padded_height_map_chunk_extent; |
pub use height_map::triangulate_height_map; |
pub use height_map::Height; |
pub use height_map::HeightMapMeshBuffer; |
pub use surface_nets::padded_surface_nets_chunk_extent; |
pub use surface_nets::surface_nets; |
pub use surface_nets::SignedDistance; |
pub use surface_nets::SurfaceNetsBuffer; |
Modules
greedy_quads | |
height_map | |
surface_nets |
Structs
PosNormMesh | |
PosNormTexMesh |